import datetime
from peewee import BigAutoField, BigIntegerField, CharField, IntegerField, DecimalField, SmallIntegerField
from playhouse.mysql_ext import JSONField
from common.model.abstrct import AbstractModel, IntEnumField, AbstractModelWithID
from enums.spu_enum import SPUSKUOnSaleEnum, SPUTypeEnum, SPUPriceTypeEnum


class SPU(AbstractModel):

    class Meta:
        table_name = "tb_mall_spu"
        auto_increment_base = 100_000_000
        indexes = (
            (("mall_id", ), False),
        )

    mall_id = BigIntegerField(help_text="商城id")
    spu_id = BigAutoField(primary_key=True, help_text="商品spu id")
    spu_type = IntEnumField(default=SPUTypeEnum.real, help_text="商品类型", choices=SPUTypeEnum)
    code = CharField(max_length=32, help_text="商品唯一code")
    outer_spu_id = CharField(max_length=64, null=True, help_text="外部商品spu id")
    name = CharField(max_length=64, help_text="商品名称")
    alias = CharField(max_length=128, help_text="商品别名", null=True)

    # 商品是否在售 优先以时间为准 其次以状态
    onsale = IntEnumField(default=SPUSKUOnSaleEnum.offsale, choices=SPUSKUOnSaleEnum, help_text="商品是否在售")
    start_timestamp = IntegerField(null=True, help_text="开始销售时间")
    end_timestamp = IntegerField(null=True, help_text="结束销售时间")

    carousel_images = JSONField(null=True, help_text="商品轮播图片")
    thu_images = JSONField(null=True, help_text="商品缩略图")
    detail_images = JSONField(null=True, help_text="商品详情图")
    video = CharField(max_length=255, help_text="商品视频介绍", null=True)

    total_quantity = IntegerField(default=0, help_text="商品总库存")
    currency_code = CharField(help_text="商品价格的币种,取自币种表里面的code,取tenant的默认币种", default="CNY")
    original_price = DecimalField(null=True, help_text="商品原价")
    sale_price = DecimalField(default=0, null=True, help_text="商品售价")
    cost_price = DecimalField(null=True, help_text="成本价")
    original_point = IntegerField(null=True, help_text="原积分值")
    cost_point = IntegerField(null=True, help_text="消耗积分值")
    price_type = IntEnumField(default=SPUPriceTypeEnum.money, help_text="商品的定价类型", choices=SPUPriceTypeEnum)

    sold_num = IntegerField(default=0, help_text="已售量")
    default_sku_id = BigIntegerField(help_text="商品首sku", null=True)

    extend_info = JSONField(null=True, help_text="商品的扩展信息，仅做展示，不涉及任何逻辑")

    def is_onsale(self, dt=None):
        """
        判断当前spu是否在售
        :param dt:
        :return:
        """
        order_time = dt or datetime.datetime.now()
        if self.onsale:
            return True
        else:
            if self.start_timestamp and self.start_timestamp > order_time:
                return False
            if self.end_timestamp and self.end_timestamp < order_time:
                return False
            return True


class SKU(AbstractModel):

    class Meta:
        table_name = "tb_mall_sku"
        auto_increment_base = 500_000_000
        indexes = (
            (("mall_id", ), False),
        )

    mall_id = BigIntegerField(help_text="商城id")
    spu_id = BigIntegerField(help_text="spu id")
    sku_id = BigAutoField(primary_key=True, help_text="sku id")
    outer_sku_id = CharField(max_length=32, help_text="外部sku id", null=True)

    carousel_images = JSONField(null=True, help_text="轮播图片")
    thu_images = JSONField(null=True, help_text="缩略图")
    detail_images = JSONField(null=True, help_text="详情图")

    total_quantity = IntegerField(default=0, help_text="sku库存")
    prehold_quantity = IntegerField(default=0, help_text="预扣库存")
    currency_code = CharField(help_text="sku价格的币种")
    original_price = DecimalField(null=True, help_text="sku原价")
    sale_price = DecimalField(default=0, null=True, help_text="sku售价")
    cost_price = DecimalField(null=True, help_text="成本价")
    original_point = IntegerField(null=True, help_text="原积分值")
    cost_point = IntegerField(null=True, help_text="消耗积分值")
    price_type = IntEnumField(default=SPUPriceTypeEnum.money, help_text="sku的定价类型 冗余", choices=SPUPriceTypeEnum)
    sold_num = IntegerField(default=0, help_text="已售量")

    onsale = IntEnumField(default=SPUSKUOnSaleEnum.offsale, choices=SPUSKUOnSaleEnum, help_text="商品是否在售")
    start_timestamp = IntegerField(null=True, help_text="开始销售时间")
    end_timestamp = IntegerField(null=True, help_text="结束销售时间")

    extend_info = JSONField(null=True, help_text="商品的扩展信息，仅做展示，不涉及任何逻辑")

    def is_onsale(self, dt=None):
        """
        判断当前sku是否在售
        :param dt:
        :return:
        """
        order_time = dt or datetime.datetime.now()
        if self.onsale:
            return True
        else:
            if self.start_timestamp and self.start_timestamp > order_time:
                return False
            if self.end_timestamp and self.end_timestamp < order_time:
                return False
            return True


# spu和属性名的关系 表示一个spu有多个属性
class MiddleSPUAttributeKey(AbstractModelWithID):

    class Meta:
        table_name = "tb_mid_spu_attribute_key"
        auto_increment_base = 100_000_000
        indexes = (
            (("mall_id", "spu_id", "attribute_key_id"), True),
            (("attribute_key_id", ), False)  # 这个看是否需要做 某个属性有多少个spu在使用这个功能
        )
    mall_id = BigIntegerField(help_text="mall_id")
    spu_id = BigIntegerField(help_text="spu id")
    attribute_key_id = BigIntegerField(help_text="attribute id")
    seq = SmallIntegerField(default=50, help_text="排序值,同一个spu之间存在不同的属性值在前面")
    attribute_value_list = JSONField(help_text="当前属性值在当前商品中的排序")


# sku和属性值的关系
class MiddleSKUAttributeValue(AbstractModelWithID):
    class Meta:
        table_name = "tb_mid_sku_attribute_value"
        auto_increment_base = 500_000_000
        indexes = (
            (("mall_id", "spu_id", "sku_id", "attribute_value_id"), True),
            (("attribute_value_id", ), False),   # 某个属性值有多少个sku在使用

        )
    mall_id = BigIntegerField(help_text="mall id")
    spu_id = BigIntegerField(help_text="spu id")
    sku_id = BigIntegerField(help_text="sku id")
    attribute_key_id = BigIntegerField(help_text="属性名id")
    attribute_value_id = BigIntegerField(help_text="属性值id")
    # seq = SmallIntegerField(default=50, help_text="排序值，同一个spu的sku之间,对于属性值的排序")


class MiddleSPUCategory(AbstractModelWithID):

    class Meta:
        table_name = "tb_mid_spu_category"

    mall_id = BigIntegerField(help_text="mall id")
    spu_id = BigIntegerField(help_text="spu id")
    category_id = BigIntegerField(help_text="category id")
